package com.moxingzhegroup;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.google.gson.Gson;
import com.moxingzhegroup.entity.CheckAppUpdateReturnPojo;
import com.moxingzhegroup.util.APKVersionCodeUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.MessageFormat;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * @author LiaoRun
 */
public class AutoUpdater {
    private static final String TAG = AutoUpdater.class.toString();

    /*
     保存APK的文件名
     */
    private static final String SAVE_FILE_NAME = "my.apk";
    private static File apkFile;

    private static int progress;// 当前进度
    // 应用程序Context
    private final Context mContext;

    /*
     是否是最新的应用,默认为false
     */
    private static boolean intercept = false;


    // 进度条与通知UI刷新的handler和msg常量
    private ProgressBar mProgress;
    private TextView txtStatus;

    private static final int DOWN_UPDATE = 1;
    private static final int DOWN_OVER = 2;
    private static final int SHOWDOWN = 3;


    private String downloadAppUrl;

    public AutoUpdater(Context context) {
        mContext = context;
        apkFile = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), SAVE_FILE_NAME);

        if (apkFile.exists()) {

            Log.d(TAG, "AutoUpdater: " + apkFile.getAbsolutePath());
        } else {
            Log.d(TAG, "AutoUpdater: 安装app的路径不存在");
        }
    }

    public void showUpdateDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("软件版本更新");
        builder.setMessage("有最新的软件包，请下载并安装!");
        builder.setPositiveButton("立即下载", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                showDownloadDialog();
            }
        });
        builder.setNegativeButton("以后再说", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        builder.create().show();
    }

    private void showDownloadDialog() {
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        dialog.setTitle("软件版本更新");
        LayoutInflater inflater = LayoutInflater.from(mContext);
        View v = inflater.inflate(R.layout.progress, null);
        mProgress = v.findViewById(R.id.progress);
        txtStatus = v.findViewById(R.id.txtStatus);
        dialog.setView(v);
        dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                intercept = true;
            }
        });
        dialog.show();
        downloadApk();
    }

    /**
     * 检查是否更新的内容
     */
    public void checkUpdate() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d(TAG, "run: " + APKVersionCodeUtils.getVersionCode(mContext));
                Log.d(TAG, "run: " + APKVersionCodeUtils.getVerName(mContext));

                String url = Constants.BASE_URL + "/appversion/findone";
                OkHttpClient okHttpClient = new OkHttpClient();

                Request request = new Request.Builder()
                        .get()
                        .url(url)
                        .build();

                okHttpClient.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(@NonNull Call call, @NonNull IOException e) {
                        Log.d(TAG, "onFailure: " + e.getMessage());

                    }

                    @Override
                    public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                        if (response.isSuccessful()) {

                            Gson gson = new Gson();
                            assert response.body() != null;
                            CheckAppUpdateReturnPojo body = gson.fromJson(response.body().string(), CheckAppUpdateReturnPojo.class);


                            assert body != null;
                            String versionNumber = body.getData().getVersionNumber();

                            if (APKVersionCodeUtils.getVerName(mContext).compareTo(versionNumber) < 0) {
                                Log.d(TAG, "onResponse: 有App更新");

                                downloadAppUrl = body.getData().getUrl();

                                mHandler.sendEmptyMessage(SHOWDOWN);
                            } else {
                                Log.d(TAG, "onResponse: 没有App更新");
                            }
                        } else {
                            Log.d(TAG, "onResponse: " + response.message());
                            Toast.makeText(mContext, response.message(), Toast.LENGTH_SHORT).show();
                        }
                    }
                });
            }
        }).start();
    }

    /**
     * 从服务器下载APK安装包
     */
    public void downloadApk() {
        // 下载线程
        Thread downLoadThread = new Thread(DownApkWork);
        downLoadThread.start();
    }

    private final Runnable DownApkWork = new Runnable() {
        @Override
        public void run() {
            URL url;
            try {
                // 下载安装包的网络路径
                url = new URL(downloadAppUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.connect();
                int length = conn.getContentLength();
                InputStream ins = conn.getInputStream();
                FileOutputStream fos = new FileOutputStream(apkFile);
                int count = 0;
                byte[] buf = new byte[1024];
                while (!intercept) {
                    int numRead = ins.read(buf);

                    if (numRead <= 0) {
                        // 下载完成通知安装
                        Log.d(TAG, "下载的总数" + count);
                        Log.d(TAG, "文件的长度" + length);
                        Log.d(TAG, "最后一次读出的长度" + numRead);

                        // 怀疑没有关闭修改安装包的文件流所以解析失败

                        Log.d(TAG, "run: 关闭了Input and out Stream");

                        fos.close();
                        ins.close();


                        mHandler.sendEmptyMessage(DOWN_OVER);
                        intercept = true;
                        break;
                    } else {
                        count += numRead;

                        // 计算下载进度
                        Log.d(TAG, "run: count" + count);
                        Log.d(TAG, "run: Length" + length);
                        Log.d(TAG, "run: numRead" + numRead);

                        progress = (int) (((float) count / length) * 100);

                        // 为啥下载进度不能100%，排除修改
                        // 吧最后一个读出来的-1 也算到读出的byte数目上了，导致显示99%
                        // 已修改
                        Log.d(TAG, "run: 下载进度" + progress);

                        // 下载进度
                        mHandler.sendEmptyMessage(DOWN_UPDATE);
                    }

                    fos.write(buf, 0, numRead);
                }


            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * 安装APK内容
     */
    public void installApk() {
        try {
            if (!apkFile.exists()) {
                return;
            }

            Intent intent = new Intent(Intent.ACTION_VIEW);
            //安装完成后打开新版本
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // 给目标应用一个临时授权
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {//判断版本大于等于7.0
                //如果SDK版本>=24，即：Build.VERSION.SDK_INT >= 24，使用FileProvider兼容安装apk
                String packageName = mContext.getApplicationContext().getPackageName();
                String authority = packageName + ".fileProvider";
                Uri apkUri = FileProvider.getUriForFile(mContext, authority, apkFile);
                intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
            }
            mContext.startActivity(intent);
            //安装完之后会提示”完成” “打开”。
            android.os.Process.killProcess(android.os.Process.myPid());


        } catch (Exception e) {
            Log.d(TAG, "installAPK: " + e.getMessage());
            Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }


    private final Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case SHOWDOWN:
                    showUpdateDialog();
                    break;
                case DOWN_UPDATE:
                    txtStatus.setText(MessageFormat.format("{0}%", progress));
                    mProgress.setProgress(progress);
                    break;
                case DOWN_OVER:
                    Toast.makeText(mContext, "下载完毕", Toast.LENGTH_SHORT).show();
                    installApk();
                    break;
                default:
                    break;
            }
            return false;
        }
    });

}